package wetalk.software.bupt.com.wetalk.application;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;

import com.jyt.message.Message;
import com.jyt.util.MySerializable;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.datatype.BmobPointer;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.UpdateListener;
import wetalk.software.bupt.com.wetalk.DB.WeTalkDB;
import wetalk.software.bupt.com.wetalk.communicate.AndroidClientService;
import wetalk.software.bupt.com.wetalk.listener.PushListener;
import wetalk.software.bupt.com.wetalk.model.po.ChatUser;
import wetalk.software.bupt.com.wetalk.model.po.Relation;
import wetalk.software.bupt.com.wetalk.model.po.User;
import wetalk.software.bupt.com.wetalk.model.po.WeTalkUser;
import wetalk.software.bupt.com.wetalk.util.SharePreferenceUtil;
import wetalk.software.bupt.com.wetalk.util.WeTalkConfig;
import wetalk.software.bupt.com.wetalk.util.WeTalkLog;

import static android.content.Context.BIND_AUTO_CREATE;
import static wetalk.software.bupt.com.wetalk.model.OnLoginListener.TAG;

/**
 * Created by zhangjie on 2017/12/7.
 */

public class UserManager {

    private AndroidClientService.SendBinder sendBinder;

    private ServiceConnection connection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            sendBinder= (AndroidClientService.SendBinder) iBinder;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    private static final int LOGIN_SUCCESS=1;
    private static final int LOGIN_FAIL=0;


    Context globalContext;

    private boolean isBound=false;
    /**
     * 用户表中所关联的好友字段
     */
    public static final String COLUMN_NAME_CONTACTS = "contacts";

    /**
     * 用户表中所关联的黑名单列表
     */
    public static final String COLUMN_NAME_BLACKLIST = "blacklist";

    Context context;
    // 创建private static类实例
    private volatile static UserManager INSTANCE;
    //同步锁
    private static Object INSTANCE_LOCK = new Object();

    /**
     * 使用单例模式创建
     */
    public static UserManager getInstance(Context context) {
        if (INSTANCE == null)
            synchronized (INSTANCE_LOCK) {
                if (INSTANCE == null) {
                    INSTANCE = new UserManager();
                }
                INSTANCE.init(context);
            }
        return INSTANCE;
    }



    /**
     * 初始化
     * @Title: init
     * @Description: TODO
     * @param  context
     * @return void
     * @throws
     */
    public void init(Context context) {
        this.globalContext = context;
        this.context=context;
    }


    public void unBindService(){
        WeTalkLog.i("connection");
        if(isBound){
            globalContext.unbindService(connection);
            isBound=false;
        }
    }

    public String getCurrentUserObjectId(){
        return getCurrentUser()!=null ? String.valueOf(getCurrentUser().getUserID()):"";
    }

    public ChatUser getCurrentUser() {
        return ChatUser.getCurrentUser(context);
    }

    public void queryUserById(String objectId, final FindListener<ChatUser> findCallback) {
        BmobQuery<ChatUser> query = new BmobQuery();
        query.addWhereEqualTo("objectId", objectId);
        query.findObjects(this.context, new FindListener<ChatUser>() {
            public void onSuccess(List<ChatUser> arg0) {
                findCallback.onSuccess(arg0);
            }

            public void onError(int arg0, String arg1) {
                findCallback.onError(arg0, arg1);
            }
        });
    }

    public void queryCurrentContactList(final FindListener<ChatUser> callback) {
        BmobQuery<ChatUser> query = new BmobQuery();
        query.order("-updatedAt");
        query.setLimit(WeTalkConfig.LIMIT_CONTACTS);
        query.addWhereRelatedTo("contacts", new BmobPointer(this.getCurrentUser()));
        query.findObjects(this.context, new FindListener<ChatUser>() {
            public void onError(int arg0, String arg1) {
                callback.onError(arg0, arg1);
            }

            public void onSuccess(final List<ChatUser> friends) {
                if (friends != null && friends.size() > 0) {
                    WeTalkDB.create(UserManager.this.context).saveOrCheckContactList(friends);
                    UserManager.this.queryBlackList(new FindListener<ChatUser>() {
                        public void onError(int arg0, String arg1) {
                            if (arg0 != 1000) {
                                WeTalkLog.i("查询用户的黑名单列表失败:" + arg1);
                            }

                            callback.onSuccess(friends);
                        }

                        public void onSuccess(List<ChatUser> blacklist) {
                            WeTalkDB.create(UserManager.this.context).batchAddBlack(blacklist);
                            callback.onSuccess(WeTalkDB.create(UserManager.this.context).getContactsWithoutBlack(friends, blacklist));
                        }
                    });
                } else {
                    WeTalkDB.create(UserManager.this.context).deleteAllContact();
                    callback.onError(1000, "暂无好友");
                }

            }
        });
    }

    public void queryBlackList(final FindListener<ChatUser> callback) {
        BmobQuery<ChatUser> query = new BmobQuery();
        query.addWhereRelatedTo("blacklist", new BmobPointer(this.getCurrentUser()));
        query.findObjects(this.context, new FindListener<ChatUser>() {
            public void onError(int arg0, String arg1) {
                callback.onError(arg0, arg1);
            }

            public void onSuccess(List<ChatUser> arg0) {
                if(arg0 != null && arg0.size() > 0) {
                    callback.onSuccess(arg0);
                } else {
                    callback.onError(1000, "暂无黑名单用户");
                }

            }
        });
    }

    public void addContactAfterAgree(String targetName, final FindListener<ChatUser> findCallback) {
        this.queryUserByName(targetName, new FindListener<ChatUser>() {
            public void onError(int arg0, String arg1) {
                findCallback.onError(arg0, arg1);
            }

            public void onSuccess(List<ChatUser> arg0) {
                UserManager.this.addRelation((User)arg0.get(0));
                WeTalkDB.create(UserManager.this.context).saveContact((ChatUser)arg0.get(0));
                findCallback.onSuccess(arg0);
            }
        });
    }

    public void logout() {
        //登出操作
        // User.logOut(this.context);
    }

    public void queryUserByName(String username, final FindListener<ChatUser> findCallback) {
        BmobQuery<ChatUser> query = new BmobQuery();
        query.addWhereEqualTo("username", username);
        query.findObjects(this.context, new FindListener<ChatUser>() {
            public void onSuccess(List<ChatUser> arg0) {
                findCallback.onSuccess(arg0);
            }

            public void onError(int arg0, String arg1) {
                findCallback.onError(arg0, arg1);
            }
        });
    }

    private void addRelation(User user, UpdateListener callback) {
        ChatUser newUser = new ChatUser();
        Relation relation = new Relation();
        relation.add(user);
        newUser.setContacts(relation);
        newUser.setUserId(this.getCurrentUserObjectId());
        // 好像是更新用户信息？
        // newUser.update(this.context, callback);
    }

    private void addRelation(User user) {
        this.addRelation(user, new UpdateListener() {
            public void onSuccess() {
            }

            public void onFailure(int arg0, String arg1) {
                WeTalkLog.i("addRelation onFailure：" + arg0 + ",errorMsg = " + arg1);
            }
        });
    }

    //登录时发送消息，在线程中发送消息
    public void login(final String name,final String password){
        final Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Intent bindIntent = new Intent(globalContext, AndroidClientService.class);
                    isBound=globalContext.bindService(bindIntent, connection, BIND_AUTO_CREATE);
                    Log.d("是否绑定成功?",isBound+"");
                    Log.d("查看Binder",sendBinder+"");
                    sendLogin(createSendMessage(name,password),new PushListener() {
                        @Override
                        public void onSuccess() {
                            WeTalkLog.i("baseSendMessage---> pushMessage:发送成功");

                        }
                        @Override
                        public void onFailure(int arg0, String arg1) {
                            WeTalkLog.i("baseSendMessage---> pushMessage:发送失败" + arg1);

                            //Toast.makeText(context,arg1+"请稍后再试",Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }


    //创建发送函数

    private void sendLogin(final JSONObject json, PushListener pushCallback) throws JSONException {
        Log.i(TAG, "send-json: "+json);
        byte[] bs;
        bs = MySerializable.object_bytes(json.toString());

        SharePreferenceUtil sharePreferenceUtil=new SharePreferenceUtil(context,"WeTalk_SP");
        String uniqueID=sharePreferenceUtil.getValue("uniqueID");
        Message login = new Message(uniqueID,"sys_login","login",bs);
        if (sendBinder!=null) {
            sendBinder.sendMessage(login);
            pushCallback.onSuccess();
        } else {
            pushCallback.onFailure(1,"no sendBinder");
        }
    }

    //关闭androidClient函数
    public void closeAndroidClient(PushListener pushCallback){
        //sendBinder.destroyAndroidClient();
        pushCallback.onSuccess();
    }

    public JSONObject createSendMessage(String name,String password) {
        try{
            JSONObject json = new JSONObject();
            json.put(WeTalkUser.PUSH_KEY_USERNAME,name);
            json.put(WeTalkUser.PUSH_KEY_PASSWORD,password);
            return json;
        }
        catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }
}
